Using Thread.Sleep
in a test might introduce unpredictable and inconsistent results depending on the environment. Furthermore, it will
block the thread, which means the system resources are not being fully used.
[TestMethod]
public void SomeTest()
{
Thread.Sleep(500); // Noncompliant
// assertions...
}
An alternative is a task-based asynchronous approach, using async and await.
More specifically the Task.Delay method should be
used, because of the following advantages:
- It is asynchronous: The thread will not be blocked, but instead will be reused by other operations
- It is more precise in timing the delay than
Thread.Sleep
- It can be canceled and continued, which gives more flexibility and control in the timing of your code
[TestMethod]
public async Task SomeTest()
{
await Task.Delay(500);
// assertions...
}
Another scenario is when some data might need to be mocked using Moq, and a delay needs to be
introduced:
[TestMethod]
public void UserService_Test()
{
var userService = new Mock<UserService>();
var expected = new User();
userService
.Setup(m => m.GetUserById(42))
.Returns(() =>
{
Thread.Sleep(500); // Noncompliant
return Task.FromResult(expected);
});
// assertions...
}
An alternative to Thread.Sleep
while mocking with Moq
is to use ReturnsAsync
and pass the amount of time to
delay there:
[TestMethod]
public void UserService_Test()
{
var userService = new Mock<UserService>();
var expected = new User();
userService
.Setup(m => m.GetUserById(42))
.ReturnsAsync(expected, TimeSpan.FromMilliseconds(500));
// assertions...
}